package loyaltypartner.dao;

import hackathon1212.EMF;

import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.Query;


public class PaybackDAO 
{
	//Avoiding lazy instantiation.
	private static final PaybackDAO singleton = new PaybackDAO();
	private int TOPID = 0;
	
	public static final PaybackDAO fetchDAO() {return singleton;}
	
	private PaybackDAO()
	{
		init();
	}
	
	private void init()
	{
		Properties prop = new Properties();
		try 
		{
			prop.load(getClass().getResourceAsStream("data.properties"));
		} 
		catch (IOException e) 
		{
//					e.printStackTrace();
		}
		for (Enumeration<Object> en = prop.keys();en.hasMoreElements();) 
		{
			String key = (String)en.nextElement();
			String value = prop.getProperty(key);
			
			Member member = decode(key, value);
			
			this.setMember(member);
			
			if(this.TOPID<Integer.parseInt(key))
				this.TOPID = Integer.parseInt(key);
		}
	}
	
	private Member decode(String key, String value)
	{
		String[] values = value.split(",");
		return new Member(key, values[0], values[1], values[2], values[3], values[4], Integer.parseInt(values[5]));
	}
	
	public synchronized Member createNewMember(String firstName, String lastName, String PIN, String email, String phoneNumber)
	{
		Member newMember = new Member(String.format(String.format("%%0%dd", 7), ++this.TOPID), firstName, lastName, PIN, email, phoneNumber, 0);
		
		this.setMember(newMember);
		
		return newMember;
	}
	
	public synchronized void blockMember(String memberID)
	{
		Member member = this.getMember(memberID);
		if(member != null)
		{
			member.setStatus(MemberStatus.BLOCKED);
			this.setMember(member);
		}
	}
	
	public int checkPointBalance(String memberID)
	{
		Member member = this.getMember(memberID);
		if(member == null)
			return Integer.MIN_VALUE;
		return member.getBalance();
	}
	
	public synchronized String collectPoints(String memberID, int point)
	{
		Member member = this.getMember(memberID);
		
		if(member == null)
			return "Invalid member ID.";
		if(point<0)
			return "Point cannot be negative.";
			
		member.setBalance(member.getBalance()+point);
		this.setMember(member);

		return String.valueOf(member.getBalance());
	}
	
	public synchronized String redeemPoints(String memberID, int point)
	{
		Member member = this.getMember(memberID);
		
		if(member == null)
			return "Invalid member ID.";
		if(member.getStatus()==MemberStatus.BLOCKED)
			return "Member account is blocked.";
		if(point<0)
			return "Point cannot be negative.";
		if(member.getBalance()<point)
			return "Insufficient points.";
		
		member.setBalance(member.getBalance()-point);
		this.setMember(member);
		
		return String.valueOf(member.getBalance());
	}

	@SuppressWarnings("rawtypes")
	private Member getMember(String memberID)
	{
		Member member = null;
		
		final EntityManager em = EMF.get().createEntityManager();
		
		try
		{
			Query query=em.createQuery("SELECT member FROM Member member WHERE member.memberID = :MEMBERID ");
			query.setParameter("MEMBERID", memberID);
			List resultList = query.getResultList();
			if(resultList.size()>0)
				member = (Member)resultList.get(0);
		}
		catch(Exception exc)
		{
//				exc.printStackTrace(System.err);
		}
		finally
		{
			em.close();
		}
		
		return member;
	}
	
	private void setMember(Member member)
	{
		final EntityManager em = EMF.get().createEntityManager();
		try
		{
			em.merge(member);
		}
		catch(Exception exc)
		{
//				exc.printStackTrace(System.err);
		}
		finally
		{
			em.close();
		}
	}
}
